/*
 * Resources.java
 *
 *  
 */
package org.msb.finance.app;

import java.awt.Image;
import java.net.URL;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.KeyStroke;

/**
 * The {@code Resources} class handles accessing various types of resources from a {@link ResourceBundle} object.
 * 
 * @author Marc Boudreau
 * 
 */
public class Resources {

	/**
	 * The {@link ResourceBundle} object from which this instance will retrieve instances.
	 */
	private ResourceBundle bundle;

	/**
	 * Creates a new instance that will retrieve resources from the provided {@link ResourceBundle} object.
	 * 
	 * @param bundle
	 *            The {@link ResourceBundle} object to use.
	 */
	public Resources(ResourceBundle bundle) {
		this.bundle = bundle;
	}

	/**
	 * Creates a new instance that will retrieve resources from the {@link ResourceBundle} object found with the
	 * provided base name.
	 * 
	 * @param baseName
	 *            A {@link String} object containing the base name used to find the {@link ResourceBundle} object.
	 */
	public Resources(String baseName) {
		this.bundle = ResourceBundle.getBundle(baseName);
	}

	/**
	 * Retrieves a text resource using the provided key. No further transformations are applied to the text resource
	 * found. If the resource cannot be found, the result is {@code "!" + key + "!"}.
	 * 
	 * @param key
	 *            A {@link String} object containing the key to use to locate the resource.
	 * 
	 * @return A {@link String} object containing the text resource found.
	 */
	public String getString(String key) {
		final String DELIM = "!"; //$NON-NLS-1$

		try {
			return this.bundle.getString(key);
		} catch (MissingResourceException ex) {
			return DELIM + key + DELIM;
		}
	}

	/**
	 * Retrieves an image resource using the provided key. The image data is loaded by locating a base name for the
	 * image file in the {@link ResourceBundle} object, then using this class' {@link ClassLoader} object to locate the
	 * image file. If the image data cannot be located for any reason, {@code null} is returned.
	 * 
	 * @param key
	 *            A {@link String} object containing the key to use to locate the resource.
	 * 
	 * @return An {@link Icon} object containing the image resource found.
	 */
	public Icon getIcon(String key) {
		return getImageIcon(key);
	}

	/**
	 * Retrieves an image resource using the provided key. The image data is loaded by locating a base name for the
	 * image file in the {@link ResourceBundle} object, then using this class' {@link ClassLoader} object to locate the
	 * image file. If the image data cannot be located for any reason, {@code null} is returned.
	 * 
	 * @param key
	 *            A {@link String} object containing the key to use to locate the resource.
	 * 
	 * @return An {@link Image} object containing the image resource found.
	 */
	public Image getImage(String key) {
		ImageIcon imageIcon = getImageIcon(key);
		if (null != imageIcon) {
			return imageIcon.getImage();
		}

		return null;
	}

	private ImageIcon getImageIcon(String key) {
		final String PREFIX = "images/"; //$NON-NLS-1$
		final String SUFFIX = ".png"; //$NON-NLS-1$
		try {
			String base = this.bundle.getString(key);
			URL url = getClass().getClassLoader().getResource(PREFIX + base + SUFFIX);
			if (null != url) {
				return new ImageIcon(url);
			}
		} catch (MissingResourceException ex) {
			// Fall through and return the default value.
		}

		return null;
	}

	/**
	 * Retrieves a single character resource using the provided key. The resource is obtained as a text resource, but
	 * only its first character is returned. If the underlying text resource cannot be retrieved, or it's an empty
	 * string, the character {@code '\0'} is returned.
	 * 
	 * @param key
	 *            A {@link String} object containing the key to use to locate the resource.
	 * 
	 * @return The {@code char} value of the resource.
	 */
	public char getCharacter(String key) {
		try {
			String s = this.bundle.getString(key);
			if (0 < s.length()) {
				return s.charAt(0);
			}
		} catch (MissingResourceException ex) {
			// Fall through and return the default value.
		}

		return '\0';
	}

	/**
	 * Retrieves a key stroke resource using the provided key. The key stroke is obtained by retrieving a text resource,
	 * which describes the key stroke, and then retrieving that key stroke.
	 * 
	 * @param key
	 *            A {@link String} object containing the key to use to locate the resource.
	 * 
	 * @return A {@link KeyStroke} object containing the key stroke resource found.
	 */
	public KeyStroke getKeystroke(String key) {
		try {
			String s = this.bundle.getString(key);
			return KeyStroke.getKeyStroke(s);
		} catch (MissingResourceException ex) {
			return null;
		}
	}

	/**
	 * Retrieves an integer resource using the provided key. The integer is obtained by retrieving a text resource and
	 * parsing as an integer.
	 * 
	 * @param key
	 *            A {@link String} object containing the key to use to locate the resource.
	 * 
	 * @return The resource found as an {@code int} value.
	 */
	public int getInteger(String key) {
		try {
			String s = this.bundle.getString(key);
			return Integer.parseInt(s);
		} catch (MissingResourceException ex) {
			// Fall through and return the default value.
		} catch (NumberFormatException ex) {
			// Fall through and return the default value.
		}

		return -1;
	}
}
